package com.sky.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.annotation.AutoFill;
import com.sky.constant.MessageConstant;
import com.sky.constant.StatusConstant;
import com.sky.dto.DishDTO;
import com.sky.dto.DishPageQueryDTO;
import com.sky.entity.Dish;
import com.sky.entity.DishFlavor;
import com.sky.entity.Setmeal;
import com.sky.entity.SetmealDish;
import com.sky.enumeration.OperationType;
import com.sky.exception.DeletionNotAllowedException;
import com.sky.mapper.DishFlavorMapper;
import com.sky.mapper.DishMapper;
import com.sky.mapper.SetmealDishMapper;
import com.sky.mapper.SetmealMapper;
import com.sky.result.PageResult;
import com.sky.service.DishService;
import com.sky.vo.DishVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
public class DishServiceImpl implements DishService {

    @Autowired
    private DishMapper dishMapper;

    @Autowired
    private DishFlavorMapper dishFlavorMapper;

    @Autowired
    private SetmealDishMapper setmealDishMapper;

    @Autowired
    private SetmealMapper setmealMapper;
    @Transactional
    @Override
    public void add(DishDTO dishDTO) {
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO, dish);
        dish.setStatus(StatusConstant.ENABLE);
        dishMapper.insert(dish);

        List<DishFlavor> flavors = dishDTO.getFlavors();
        if (flavors == null || flavors.size() == 0) {
            flavors.forEach(flavor -> {
                flavor.setDishId(dish.getId());
            });
            dishFlavorMapper.insert(flavors);
        }

    }

    @Override
    public PageResult page(DishPageQueryDTO dishPageQueryDTO) {
        PageHelper.startPage(dishPageQueryDTO.getPage(), dishPageQueryDTO.getPageSize());
        Page<DishVO> dishes = dishMapper.page(dishPageQueryDTO);

        return new PageResult(dishes.getTotal(), dishes.getResult());
    }

    @Override
    public DishDTO getById(Integer id) {
        DishDTO dishDTO = dishMapper.getById(id);
        List<DishFlavor> dishFlavorList = dishFlavorMapper.getByDishId(id);
        dishDTO.setFlavors(dishFlavorList);
        return dishDTO;
    }

    @Transactional
    @Override
    public void delByIds(Integer[] ids) {
        List<Dish> dishList = dishMapper.getByIds(ids);
        dishList.forEach(dish -> {
            if (dish.getStatus().equals(StatusConstant.ENABLE)) {
                throw new DeletionNotAllowedException("菜品 [" + dish.getName() + "] 已启用，不能删除");
            }
        });
        List<SetmealDish> setmealDishList = setmealDishMapper.getByDishId(ids);
        if (setmealDishList != null && setmealDishList.size() > 0){
            throw new DeletionNotAllowedException(MessageConstant.DISH_BE_RELATED_BY_SETMEAL);
        }
        dishMapper.delByIds(ids);
    }

    @Override
    public void updateStatus(Integer id, Integer status) {
        // 如果菜品已经被套餐引用，则会停售套餐
        if (status.equals(StatusConstant.DISABLE)) {
            List<SetmealDish> list = setmealDishMapper.getListByDishId(id);
            if (list != null && list.size() > 0) {
                // 说明菜品关联了套餐
                Integer[] integers = new Integer[list.size()];
                for (int i = 0; i < list.size(); i++) {
                    integers[i] = list.get(i).getSetmealId().intValue();
                }
                List<Setmeal> setmealList = setmealMapper.getByIds(integers);
                setmealMapper.setStatusByIds(integers);

            }
        }
        Dish dish = new Dish();
        dish.setId((long)id);
        dish.setStatus(status);
        dishMapper.update(dish);
    }

    @Transactional
    @AutoFill(OperationType.UPDATE)
    @Override
    public void update(DishDTO dishDTO) {
        Dish dish = new Dish();
        BeanUtils.copyProperties(dishDTO, dish);
        List<DishFlavor> flavorList = dishDTO.getFlavors();
        if (flavorList != null && flavorList.size() > 0) {
            dishFlavorMapper.delById(dish.getId());
            flavorList.forEach(flavor -> {
                flavor.setDishId(dish.getId());
            });
            dishFlavorMapper.insert(flavorList);
        }
        dishMapper.update(dish);
    }

    @Override
    public List<Dish> getByCategoryId(Integer categoryId) {
        List<Dish> list =  dishMapper.getByCategoryId(categoryId);
        return list;
    }

    @Override
    public List<DishVO> getByCId(Integer categoryId) {
        List<Dish> dishList = dishMapper.getByCategoryIdStatus(categoryId);
        List<DishVO> dishVOS = new ArrayList<>();
        dishList.forEach(dish -> {
            DishVO dishVO = new DishVO();
            BeanUtils.copyProperties(dish, dishVO);
            dishVO.setFlavors(dishFlavorMapper.getByDishId(dish.getId().intValue()));
            dishVOS.add(dishVO);
        });
        return dishVOS;
    }
}
